﻿using Org.BouncyCastle.Utilities.Encoders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpSM
{
    public class Sm2Util
    {
        /// <summary>
        /// 基于SM2加密
        /// </summary>
        /// <param name="srcData">源数据</param>
        /// <param name="pubKey">公钥 Hex（16进制）编码的字符</param>
        /// <returns>Hex（16进制）编码的字符</returns>
        public static string Encrypt(string srcData, string pubKey)
        {
            SM2 sm2 = new SM2(null, pubKey);
            byte[] encryptByte = sm2.encrypt(Encoding.UTF8.GetBytes(srcData));
            string result = Hex.ToHexString(encryptByte);
            if (result.StartsWith("04"))
            {
                return result.Substring(2);
            }
            return result;
        }

        /// <summary>
        /// 基于SM2解密
        /// </summary>
        /// <param name="encData">密文 Hex（16进制）编码的字符</param>
        /// <param name="priKey">密钥 Hex（16进制）编码的字符</param>
        /// <returns>原数据</returns>
        public static string Decrypt(string encData, string priKey)
        {
            SM2 sm2 = new SM2(priKey, null);
            encData = "04" + encData;
            byte[] deCode = HexUtils.decode(encData);
            byte[] decryptText = sm2.deceypt(deCode);
            return Encoding.UTF8.GetString(decryptText);
        }

        /// <summary>
        /// 生成SM2秘钥对
        /// </summary>
        /// <returns>string[0]为公钥，string[1]为私钥</returns>
        public static string[] GenerateKeyPair()
        {
            return SM2.GenerateKeyPair();
        }

        /// <summary>
        /// 基于SM2验名
        /// </summary>
        /// <param name="data">源数据</param>
        /// <param name="priKey">私钥 Hex（16进制）编码的字符</param>
        /// <returns>签名值 Hex（16进制）编码的字符</returns>
        public static string Sign(string data, string priKey)
        {
            SM2 sm2 = new SM2(priKey, null);
            return sm2.sign(data);

        }

        /// <summary>
        /// SM2验签
        /// </summary>
        /// <param name="data">源数据</param>
        /// <param name="sign">签名 Hex（16进制）编码的字符</param>
        /// <param name="pubKey">公钥 Hex（16进制）编码的字符</param>
        /// <returns>是否成功</returns>
        public static bool Verify(string data, string sign, string pubKey)
        {
            SM2 sm2 = new SM2(null, pubKey);
            return sm2.verifySign(data, sign);
        }        
    }
}
